#!/usr/bin/env node
import path from 'path';
import fs from 'fs';
import fse from 'fs-extra';
import chalk from 'chalk';
import AdmZip from 'adm-zip';
import dayjs from 'dayjs';
import child_process from 'child_process';
import os from 'os';
import { createRequire } from 'module';
import { fileURLToPath } from 'url';
import { loadEnv } from 'vite';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const require = createRequire(import.meta.url);
const env = loadEnv('production', process.cwd());

const configJson = require('../pluginTemp/config.json');
const information = require('./information.json');
const sourceMap = env.VITE_APP_BUILD_SOURCE_MAP === 'true';

checkPreview();
!sourceMap &&
  console.log(
    chalk.yellow('plugin命令打包不含有map文件。如需要线上调试，请运行npm run plugin:dev'),
  );

// 删除老的文件
const outputFiles = fs.readdirSync(path.resolve(__dirname, '../output'));
outputFiles.forEach(item => {
  if (item.endsWith('.zip')) {
    fse.removeSync(path.resolve(__dirname, `../output/${item}`));
  }
});
fse.removeSync(path.resolve(__dirname, '../pluginTemp/js'));
fse.removeSync(path.resolve(__dirname, '../pluginTemp/media'));

// copy js
let mainFileName = ''; // 主入口文件
fs.mkdirSync(path.resolve(__dirname, '../pluginTemp/js'));
fs.readdirSync(path.resolve(__dirname, '../dist/assets')).forEach(file => {
  if (path.extname(file) === '.js') {
    mainFileName = file;
    fs.copyFileSync(
      path.resolve(__dirname, `../dist/assets/${file}`),
      path.resolve(__dirname, `../pluginTemp/js/${file}`),
    );
  }
});

// copy 静态文件
if (fs.existsSync(path.resolve(__dirname, '../dist/media'))) {
  fs.mkdirSync(path.resolve(__dirname, '../pluginTemp/media'));
  fs.readdirSync(path.resolve(__dirname, '../dist/media')).forEach(file => {
    fs.copyFileSync(
      path.resolve(__dirname, `../dist/media/${file}`),
      path.resolve(__dirname, `../pluginTemp/media/${file}`),
    );
  });
}

if (!mainFileName) {
  throw new Error('未写入main字段');
}
configJson.main = mainFileName;

fs.writeFileSync(
  path.resolve(__dirname, '../pluginTemp/config.json'),
  JSON.stringify(configJson, null, 2),
  'utf8',
);

const requirementNumber = configJson['requirement-number'];
const requirementName = configJson['requirement-name'];
let internalPrefix = '';
requirementNumber &&
  requirementName &&
  (internalPrefix = `${requirementNumber}-${requirementName}-`);
const zip = new AdmZip();
zip.addLocalFolder(path.resolve(__dirname, '../pluginTemp'));
const pluginPath = path.resolve(
  __dirname,
  `../plugin-${internalPrefix}${dayjs().format('YY年MM月DD日-HH时mm分')}.zip`,
);
zip.writeZip(pluginPath);

zip.writeZip(
  path.resolve(
    __dirname,
    `../output/${internalPrefix ? internalPrefix.slice(0, -1) : '插件包'}.zip`,
  ),
);
printZip(zip);
writeBaseInformation();
console.log(chalk.blue('打包完成...'));

function printZip(zip) {
  zip.getEntries().forEach(zipEntry => console.log(zipEntry.name || zipEntry.entryName));
}

function checkPreview() {
  if (information.onlineDevMode) {
    delete information.onlineDevMode;
    fs.writeFileSync(
      path.resolve(__dirname, `./information.json`),
      JSON.stringify(information, null, 2),
      'utf8',
    );
    return;
  }
  if (
    !sourceMap &&
    !fs.existsSync(path.resolve(__dirname, '../output/preview.png')) &&
    configJson['requirement-number']
  ) {
    throw new Error('请将前端页面截图，并命名为preview.png放在output文件夹');
  }
}

function writeBaseInformation() {
  const execSync = child_process.execSync;
  const baseInformationSet = information.baseInformationSet || {};
  const baseInfomation = {};
  let currentDeveloper = '';
  try {
    currentDeveloper = execSync('git config user.name', { encoding: 'utf8' })
      .replace('\n', '')
      .replace('\r', '');
  } catch (e) {
    currentDeveloper = os.hostname();
  }
  [
    ['nodeVersion', 'node -v'],
    ['npmVersion', 'npm -v'],
    ['pnpmVersion', 'pnpm -v'],
  ].forEach(item => {
    try {
      baseInfomation[item[0]] = execSync(item[1]).toString().replace('\n', '').replace('\r', '');
    } catch (e) {}
  });
  baseInfomation.platform = os.arch().toString().replace('\n', '').replace('\r', '');
  baseInformationSet[currentDeveloper] = baseInfomation;
  information.baseInformationSet = baseInformationSet;
  fs.writeFileSync(
    path.resolve(__dirname, './information.json'),
    JSON.stringify(information, null, 2),
    'utf8',
  );
}
